//
//  MySQLConnection.h
//  LibMySQL
//
//  Created by Marcus Grenängen on 2009-07-16.
//  Copyright 2009 SneWs Soft. All rights reserved.

#import <Cocoa/Cocoa.h>
#import <mysql.h>

#import "MySQLGlobals.h"
#import "MySQLException.h"
#import "MySQLResult.h"
#import "MySQLColumn.h"
#import "MySQLParameter.h"


/*
 * @description: Implements a connection to a MySQL database.
 */
@interface MySQLConnection : NSObject
{
@protected
	MYSQL*	  _mysql;
#if MYSQL_VERSION_ID >= 50136
	MYSQL_STMT* _stmt;
#endif
	NSString* charset;
	
@private
	NSString*	  hostname;
	NSInteger	  port;
	NSString*	  database;
	NSString*	  username;
	NSString*	  password;
	NSInteger	  timeout;
	unsigned long connectionProperties;
	NSString*	  socket;
}

#pragma mark -
#pragma mark Properties, GET / SET
@property(nonatomic, readonly) NSString *charset;
@property(nonatomic, readonly, copy) NSString *hostname;
@property(nonatomic, readonly, assign) NSInteger port;
@property(nonatomic, readonly, copy) NSString *database;
@property(nonatomic, readonly, copy) NSString *username;
@property(nonatomic, readonly, copy) NSString *password;
@property(nonatomic, readonly, assign) NSInteger timeout;
@property(nonatomic, readonly, assign) unsigned long connectionProperties;
@property(nonatomic, readonly, copy) NSString *socket;

#pragma mark -
#pragma mark Static Methods
/*
 * @description: Creates a new MySQLConnection based on the connectionString data.
 *				 
 * @connectionString: Supported formats for the connection string is as follows:
 *
 *	Standard connection string: 
 *		Server=myServerAddress;Port=3306;Database=myDataBase;Uid=myUsername;Pwd=myPassword;
 *
 *	Named pipes: 
 *		Server=myServerAddress;Port=-1;Database=myDataBase;Uid=myUsername;Pwd=myPassword;
 *
 *	With charset: 
 *		Server=myServerAddress;Port=3306;Database=myDataBase;Uid=myUsername;Pwd=myPassword;Charset=utf8;
 */
+ (MySQLConnection *)connectionWithString:(NSString *)connectionString;

/*
 * @description: Creates a new MySQLConnection based on the dictionary
 *				 
 * @oDictionary: Supported key/value for the dictionary is as follows:
 *
 *  Keys:Values for standard connection:
 *		Server: myServerAddress (NSString)
 *		Port: 3306 (NSNumber)
 *		Database: myDatabase (NSString)
 *		Uid: myUserName (NSString)
 *		Pwd: myPassword (NSString)
 *		Charset: utf8 (NSString)
 *
 *	Keys:Values for named pipes:
 *		Server: myServerAddress (NSString)
 *		Port: -1 (NSNumber)
 *		Database: myDatabase (NSString)
 *		Uid: myUserName (NSString)
 *		Pwd: myPassword (NSString)
 */
+ (MySQLConnection *)connectionWithDictionary:(NSDictionary *)oDictionary;

#pragma mark -
#pragma mark Init methods

- (id) initWithHost:(NSString *)h port:(NSInteger)p;
- (id) initWithHost:(NSString *)h port:(NSInteger)p user:(NSString *)u password:(NSString *)pwd;
- (id) initWithHost:(NSString *)h port:(NSInteger)p user:(NSString *)u password:(NSString *)pwd options:(NSInteger)properties;
- (id) initWithSocket:(NSString *)s user:(NSString *)u password:(NSString *)pwd options:(NSInteger)properties;

#pragma mark -
#pragma mark Public Methods
/*
 * @description: Opens the connection to the MySQL server.
 *
 * @throws: A MySQLException is thrown if the connection fails.
 */
- (void)open;

/*
 * @description: Returns TRUE if the connection is open; 
 *				 Otherwise FALSE;
 *
 */
- (BOOL)isOpen;

/*
 * @description: Closes the connection to the MySQL server if it's open.
 */
- (void)close;

/*
 * @description: Returns a NSString* describing the version for the server we are connected to.
 * @throws: A MySQLException.
 */
- (NSString *)serverVersion;

/*
 * @description: Changes the active database for this connection
 * @throws: A MySQLException is throws if the database not could be changed.
 */
- (void)changeDatabase:(NSString *)newDatabaseName;

/*
 * @description: Changes the current user and database.
 *				 NOTE: IF the database parameter is nil or empty it will try to 
 *					   use the already exsisting database name if one is available.
 *
 * @throws: A MySQLException is throws if the login fails or that the database isn't valid.
 */
- (void)changeUser:(NSString *)user withPassword:(NSString *)pwd usingDatabase:(NSString *)db;

/*
 * @description: Changes the character set currently in use.
 * @throws: A MySQLException is thrown if the character set not could be changed
 */
- (void)changeCharacterSet:(NSString *)charsetByName;

/*
 * @description: Changes the character set currently in use.
 * @throws: A MySQLException is thrown if the encoding can't be init'ed.
 */
- (NSStringEncoding)encodingForConnection;

/*
 * @description: Gets the last inserted ID for the active database and table
 *				 using the AUTO_INCREMENT value.
 *
 * @returns: The last inserted id > 0; Or if not successfull a value < 1
 *
 * @throws: A MySQLException.
 */
- (NSInteger)lastInsertedId;

#pragma mark -
#pragma mark MySQL information extract methods
/*
 * @description: Returns information about the client
 *
 * @returns: A NSString containing the client information or nil if unsuccessfull,
 *
 * @throws: A MySQLException.
 */
- (NSString *)clientInformation;

/*
 * @description: Returns information about the host
 *
 * @returns: A NSString containing the host information or nil if unsuccessfull,
 *
 * @throws: A MySQLException.
 */
- (NSString *)hostInformation;

/*
 * @description: Returns information about the server
 *
 * @returns: A NSString containing the server information or nil if unsuccessfull,
 *
 * @throws: A MySQLException.
 */
- (NSString *)serverInformation;


#pragma mark -
#pragma mark Methods to execute diffrent SQL actions.
/*
 * @description: Run a SQL statement that returns no data.
 *				 Like UPDATE or DELETE statements.
 *
 * @returns: A value representing the number of affected rows.
 */
- (NSInteger)executeNonQuery:(NSString *)sqlCommand;

/*
 * @description: Run a SQL statement that will return a single row single column
 *				 value. The value will be returned as it's native Obj-C type
 *				 based on the MySQL value type.
 *
 * @returns: A single Obj-C result value based and converted from the MySQL value type.
 */
- (id)executeScalar:(NSString *)sqlCommand;

/*
 * @description: Run a SQL statement that will return one or more rows into a
 *				 enumerable result set for simple access.
 *
 * @returns: A MySQLResult object that conforms to the NSEnumerator class
 */
- (MySQLResult *) executeQuery:(NSString *)sqlCommand;


#pragma mark -
#pragma mark Helper Query Methods
/*
 * @description: Use this method to escape strings for "safe" usage in queries
 */
- (NSString *)escapeString:(NSString *)stringToEscape;

/*
 * @description: Use this method to escape NSDate for "safe" usage in queries.
 */
- (NSString *)escapeData:(NSData *)dataToEscape;

/*
 * @description: Use this method to get a "valid" string to use in queries.
 *				 The return string will be quoted and properly escaped depending on 
 *				 the type of data passed to the function.
 */
- (NSString *)prepareValue:(id)value;

@end





